// Description: LSBJ audio driver
// Author: JerryTech
// License: GPLv3


module LSBJ_audio_driver # (
    parameter DEF_LEN = 24,
    parameter WIDTH = 16, //Must less than LSBJ define width
    parameter FIFO_DELAY_MIN = 3
)(
    input   wire audio_clk, // Double rate of DEF_LEN * audio_bck
    input   wire reset,

    input   wire [WIDTH - 1 :0 ] left_data,
    input   wire [WIDTH - 1 :0 ] right_data,
    input   wire                 fifo_read_ready,
    output  reg                  fifo_read_en,

    output  reg                  audio_ws,
    output  reg                  audio_bck,
    output  reg                  audio_din

);

reg [6:0] counter;
reg [WIDTH - 1 :0 ] left_reg;
reg [WIDTH - 1 :0 ] right_reg;

always @ (posedge audio_clk) begin
    if(reset) begin
        counter <= (2 * 2 * DEF_LEN) - 1;
    end
    else begin
        counter <= counter == 0 ? (2 * 2 * DEF_LEN) - 1 : counter - 6'd1;
    end
end

always @ (posedge audio_clk) begin
    if(reset) begin
        audio_bck <= 0;
    end
    else begin
        audio_bck <= counter[0];
    end
end

always @ (posedge audio_clk) begin
    if(reset) begin
        audio_ws <= 0;
    end
    else if(counter == 2 * DEF_LEN)begin
        audio_ws <= 1;
    end
    else if(counter == 0) begin
        audio_ws <= 0;
    end
end

always @ (posedge audio_clk) begin
    if(reset) begin
        audio_din <= 0;
    end
    else if((counter <= 2 * WIDTH) && counter > 0)begin
        audio_din <= left_reg[((counter - 1) >> 1)];
    end
    else if((counter <= 2 * (WIDTH + DEF_LEN) ) && (counter > 2 * DEF_LEN)) begin
        audio_din <= right_reg[(counter - DEF_LEN * 2 - 1) >> 1];
    end
    else begin
        audio_din <= 0;
    end
end


always @ (posedge audio_clk) begin
    if(reset) begin
        fifo_read_en <= 0;
    end
    else if(counter == 0) begin
        fifo_read_en <= 1'b1;
    end
    else begin
        fifo_read_en <= 0;
    end
end

always @ (posedge audio_clk) begin
    if(reset) begin
        left_reg    <= 0;
        right_reg   <= 0;
    end
    else if(fifo_read_ready) begin
        if(counter == (2 * 2 * DEF_LEN) - FIFO_DELAY_MIN - 1) begin
            left_reg    <= left_data;
            right_reg   <= right_data;
        end
    end
    else begin
        left_reg    <= 0;
        right_reg   <= 0;
    end
end

endmodule

